<html>
<head><meta charset="utf-8"><title>Substitution principle · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html">Substitution principle</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="166201262"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166201262" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166201262">(May 21 2019 at 18:50)</a>:</h4>
<p>Did we ever document the following substitution principle for layouts as part of our layout/repr discussion? Or did we uncover some points that would contradict this principle?</p>
<blockquote>
<p>Once size and alignment <em>and niche</em> of twp types are the same, you can assume that size and alignment and niche are the same when these two types are wrapped in arbitrary type constructors (excluding associated types).</p>
</blockquote>
<p>It seems self-evident to me but what do I know.^^ Either way, this seems worth documenting?</p>



<a name="166201611"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166201611" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gankra <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166201611">(May 21 2019 at 18:55)</a>:</h4>
<p>i assume there is also a caveat of "excluding potential extensions to specialization"</p>



<a name="166201733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166201733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166201733">(May 21 2019 at 18:56)</a>:</h4>
<p>Need to exclude associated <em>constants</em>, too. Most kinds of parametricity-breaking constant expressions or type-level constructs (e.g. via specialization but there might be others, e.g. if <code>TypeId::of</code> was a <code>const fn</code>) can also violate this principle. And in a plausible future, there might also be associated <code>const fn</code>s that allow newtypes to differ from their contents for layout purposes.</p>
<p>And then there's the broader problem that we haven't even formally committed to <em>any</em> kind of determinism in layout computation. Even <code>struct A(i32); struct B(i32);</code> can have different layouts as far as the current state of UCG is concerned.</p>



<a name="166201911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166201911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gankra <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166201911">(May 21 2019 at 18:58)</a>:</h4>
<p>More specifically even if you guarantee size and align, field randomization may lead to a different niche position for MyGenericType&lt;T&gt;(T, u32), if the compiler chooses to randomize the order of .0 and .1 for, e.g., MyGenericType&lt;&amp;A&gt; and MyGenericType&lt;Box&lt;A&gt;&gt;</p>



<a name="166201954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166201954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166201954">(May 21 2019 at 18:59)</a>:</h4>
<p>"excluding associated anything" is really what I meant ;)</p>



<a name="166201960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166201960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gankra <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166201960">(May 21 2019 at 18:59)</a>:</h4>
<p>(lost track if you have abandonned field randomization as a feature)</p>



<a name="166201983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166201983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166201983">(May 21 2019 at 18:59)</a>:</h4>
<blockquote>
<p>Even struct A(i32); struct B(i32); can have different layouts as far as the current state of UCG is concerned.</p>
</blockquote>
<p>that is not in contradiction to my statement. "type constructors" are nominal, so A and B are different type constructors here.</p>



<a name="166202090"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202090" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202090">(May 21 2019 at 19:00)</a>:</h4>
<p>Yes, but <code>i32</code> and <code>NonZeroI32</code> are nominally different types, hence...</p>



<a name="166202141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202141">(May 21 2019 at 19:00)</a>:</h4>
<p>...?</p>



<a name="166202144"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202144" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202144">(May 21 2019 at 19:00)</a>:</h4>
<p><span class="user-mention" data-user-id="137587">@Gankro</span> </p>
<blockquote>
<p>More specifically even if you guarantee size and align, field randomization may lead to a different niche position for MyGenericType&lt;T&gt;(T, u32), if the compiler chooses to randomize the order of .0 and .1 for, e.g., MyGenericType&lt;&amp;A&gt; and MyGenericType&lt;Box&lt;A&gt;&gt;</p>
</blockquote>
<p>that would indeed be a contradiction to my statement.</p>



<a name="166202192"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202192" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202192">(May 21 2019 at 19:01)</a>:</h4>
<p><span class="user-mention" data-user-id="124289">@rkruppe</span> I dont know where you are going or what you are replying to.</p>



<a name="166202627"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202627" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202627">(May 21 2019 at 19:06)</a>:</h4>
<p>I'm trying to say that we currently don't say layout computation of structs (enums too, unions? not sure) is deterministic, <em>in particular</em> it can depend on nominal types, treating two field types with same sizes, alignments, niches, etc. differently. So a better example than my previous one would be: given <code>struct A&lt;T&gt;(T);</code> we don't guarantee that <code>A&lt;i32&gt;</code> and <code>A&lt;u32&gt;</code> are laid out the same, even though we do guarantee that <code>i32</code> and <code>u32</code> have the same size, align, and niche.</p>



<a name="166202689"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202689" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202689">(May 21 2019 at 19:07)</a>:</h4>
<p>Nominal types don't just matter "at the top level", so to speak</p>



<a name="166202839"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202839" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202839">(May 21 2019 at 19:09)</a>:</h4>
<p>Current wording for reference: <a href="https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/structs-and-tuples.md#default-layout-repr-rust" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/structs-and-tuples.md#default-layout-repr-rust">https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/structs-and-tuples.md#default-layout-repr-rust</a></p>



<a name="166202922"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202922" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202922">(May 21 2019 at 19:10)</a>:</h4>
<p>Maybe I'm misunderstanding what's meant by niche here, but the whole point of <code>NonZeroI32</code> is that it has a different niche to <code>i32</code>.</p>



<a name="166202929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202929">(May 21 2019 at 19:10)</a>:</h4>
<p>Ah, oops, you're right</p>



<a name="166202962"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166202962" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166202962">(May 21 2019 at 19:10)</a>:</h4>
<p>Pretend I used <code>#[repr(transparent)] struct WrapI32(i32);</code> for the whole time</p>



<a name="166203632"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166203632" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gankra <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166203632">(May 21 2019 at 19:19)</a>:</h4>
<p>I would think you could just use i32 and u32 :)</p>



<a name="166203769"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution%20principle/near/166203769" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Substitution.20principle.html#166203769">(May 21 2019 at 19:20)</a>:</h4>
<p><span class="user-mention" data-user-id="124289">@rkruppe</span> I see. then it becomes the same point as <span class="user-mention" data-user-id="137587">@Gankro</span>'s. I agree.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>